大綱
- 物件列舉屬性 (for-in/Object.keys)
- 物件屬性特性設定 (ES5 defineProperty / ES6 Symbol)
- ES6 Class static / getter / setter
物件 列舉屬性
- Object.keys(obj) 列舉屬性
- for-in 迴圈列舉原型鏈上的屬性
const obj = {
name: 'John',
age: 30,
}
obj.isRead = true
// 列舉屬性
Object.keys(obj) // ['name','age','isRead']
// for-in 迴圈 會列舉出包含在原型鏈中的所有屬性
// ESLint 不建議使用此
for (const key in obj) {
// 是否為該物件的屬性,而非原型鏈的
if (obj.hasOwnProperty(key)) {
const elem = object[key]
console.log(elem)
}
}
物件 屬性特性設定
- Object.defineProperty 設定屬性特性
- ES6 Symbol 無法被 for-in 或 Object.keys 列舉
// ES5 屬性不被列舉的寫法
// 設定屬性特性 (是否唯獨、可被列舉、更改...等)
Object.defineProperty(obj, 'isRead', {
value: true,
writable: true, // 是否可更改屬性
enumerable: false, // 使其無法列舉
})
// 取得該屬性的特性
Object.getOwnPropertyDescriptor(obj, '屬性名')
const isRead = Symbol()
const obj = {
name: 'John',
age: 30
}
obj[isRead] = true
console.log(obj) // {name: 'John', age: 30, Symbol(): true }
ES6 static/get/set
ES6 Static 用法
- 靜態方法不須實例化,即可被呼叫
- 但被實例化後,則靜態方法不能被呼叫 (私有方法)
- 常用於工具函式 (資料處理)
class Calculator {
constructor(str) { this.str = str }
static add(a, b) { console.log(a + b) }
hey() { return this.str }
}
const calculatorA = new Calculator('hey')
// 建立實體後,無法透過實體使用該函式
console.log(calculatorA.add) // undefined
console.log(calculatorA.hey()) // 'hey'
// 沒有建立實體即可使用
Calculator.add(1, 4) // 3
ES6 get/set 用法 (僅用於私有屬性)
- 可控制 資料 寫入 & 讀出的過程
- 可於中間作一些格式處理、錯誤偵測
- getter不會有傳入參數,setter只會有一個傳入參數
-
範例參考於此
class Option {
constructor(key, value) {
if (typeof key !== 'undefined') { this[`_${key}`] = value }
}
get color() {
if (this._color !== undefined) { return this._color }
return 'no color prop'
}
set color(value) { this._color = value }
}
const op1 = new Option('color', 'red')
op1.color = 'yellow'
const op2 = new Option('action', 'run')
op2.color = 'yellow'
ES5 getter / setter 寫法
- 使用 Object.defineProperty
- 若要使物件的屬性無法被更動 writable: false,
Object.defineProperty(obj, 'key', {
get() {
// 取得值前 可於此作format....etc
return this.name
},
set(val) {
// 設定值前可以作一些 例外判斷 (falsy...etc)
this.name = val
console.log(val)
},
})